package com.pablosz.worm;

import android.graphics.Canvas;
import android.view.SurfaceHolder;

import com.pablosz.worm.util.Hashtable;
import com.pablosz.worm.util.LifecicleComponents;
import com.pablosz.worm.util.Number;


public class Lifecicle implements Runnable
{
	public static final int STATE_NEW=1;
	public static final int STATE_READY=2;
	public static final int STATE_WAITINGFORTOUCH=3;
	public static final int STATE_RUNNING=4;
	public static final int STATE_STOPPED=5;
	public static final int STATE_FINISHING=6;
	public static final int STATE_DEAD=7;

	private int lifecicleState;
	private transient Thread thread = null;
	
	private Hashtable<Number> componentSleep = null;
	private LifecicleComponents components = null;
	
	private transient SurfaceHolder holder = null;
	
	public Lifecicle()
	{
		components = new LifecicleComponents();
		componentSleep = new Hashtable<Number>();
		
		lifecicleState = STATE_NEW;
	}
	
	public void startThread(SurfaceHolder holder)
	{
		switch(lifecicleState)
		{
			case STATE_NEW:
				break;
			case STATE_DEAD:
				break;
			default:
				lifecicleState = STATE_READY;
				break;
		}
		
		this.holder = holder;
		
		thread = new Thread(this);
		thread.start();
	}
	
	public void stopThread()
	{
		lifecicleState = STATE_STOPPED;
		thread.interrupt();
		thread = null;
	}
	
	public void addComponent(String s,LifecicleComponent c)
	{
		components.put(s, c);
		componentSleep.put(s, new Number(0));
	}

	public void run()
	{
		boolean fin=false;
		while( !fin )
		{	
			switch(lifecicleState)
			{
				case STATE_NEW:
					notifyComponentsOnInit();
					lifecicleState=STATE_READY;
					break;
					
				case STATE_READY:
					Canvas c = holder.lockCanvas();
					printComponents(c);
					holder.unlockCanvasAndPost(c);
					lifecicleState = STATE_WAITINGFORTOUCH;
					break;
					
				case STATE_STOPPED:
					break;
					
				case STATE_WAITINGFORTOUCH:
				   break;
					
				case STATE_RUNNING:	
					notifyComponentsOnProcess();
					break;
					
				case STATE_FINISHING:
					fin = notifyComponentsOnFinish();
					break;
			}
		}
		
		lifecicleState = STATE_DEAD;
	}
	
	private void notifyComponentsOnInit()
	{		
		Canvas canvas = holder.lockCanvas();
		float width = canvas.getWidth();
		float height = canvas.getHeight();
		
		// notifico el reset
		for(String k:components.getKeys())
		{
			LifecicleComponent lst = components.get(k);		
			lst.init(this, components,(long)width,(long)height);
		}
		
		holder.unlockCanvasAndPost(canvas);	
	}
	
	private void notifyComponentsOnProcess()
	{	
		Canvas canvas = holder.lockCanvas();
		
		if( canvas == null ) return;
		
		float width=canvas.getWidth();
		float height=canvas.getHeight();
		
		// motifico el show
		for(String k:components.getKeys())
		{
			LifecicleComponent lst = components.get(k);
			if( !isSleeping(k,lst) )
			{
				lst.process(this,components,(long)width,(long)height);
			}
		}
		
		printComponents(canvas);
		holder.unlockCanvasAndPost(canvas);
		
	}
	
	private void printComponents(Canvas canvas)
	{
		// notifico el print
		for(String k:components.getKeys())
		{
			LifecicleComponent lst = components.get(k);		
			lst.print(canvas);	
		}
	}
	
	private boolean isSleeping(String key,LifecicleComponent lst)
	{
		if( lst.getLifecicleDelay() == 0 )
		{
			return false;
		}

		boolean ret;
		Number sleep = componentSleep.get(key);
		
		if( sleep.value>=lst.getLifecicleDelay() )
		{
			sleep.value=0;
			ret=false;
		}
		else
		{
			sleep.value++;
			ret=true;
		}
		
//		componentSleep.put(key, sleep);
			
		return ret;
	}

	private boolean notifyComponentsOnFinish()
	{
		Canvas canvas = holder.lockCanvas();
		float width=canvas.getWidth();
		float height=canvas.getHeight();
		
		boolean fin=true;
		
		// motifico el show
		for(String k:components.getKeys())
		{
			LifecicleComponent lst = components.get(k);	
			fin=fin&&lst.finish(this, components,(long)width,(long)height);
			lst.print(canvas);
		}
		
		holder.unlockCanvasAndPost(canvas);
		
		return fin;
	}
	
	public void notifyComponentsOnTouch(long x, long y)
	{		
		lifecicleState = lifecicleState==STATE_DEAD?STATE_DEAD:STATE_RUNNING;
		
		// motifico el show
		for(String k:components.getKeys())
		{
			LifecicleComponent lst = components.get(k);		
			lst.onTouch(this,components, x,y);
		}
	}
	
	public int getLifecicleState()
	{
		return lifecicleState;
	}
	
	public void setLifecicleState(int s)
	{
		lifecicleState = s;
	}
}
